
package com.benimetum.managers;

import com.benimetum.database.Sparql;
import com.benimetum.exceptions.DatabaseConnectException;
import com.benimetum.exceptions.DatabaseWriteOrDeleteException;
import com.benimetum.items.UploadedFile;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Ethem Cem Ozkan
 * @email ethemcem.ozkan@gmail.com
 * No 07110604
 */
public class FileManager
{
    private final static String RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    private final static String ETU="http://www.benimetum.com/benimetum.owl#";
    private final static String FOAF="http://xmlns.com/foaf/0.1/";
    
    /**
     * dosyayı sisteme yükler
     * @param file
     * @param information
     * @return 
     */
    public static String uploadFile(File file, String information){
	  Random random=new Random();
	  String id="doc"+random.nextInt(10000000);
	  String type = null;
	  try {
		type = file.getCanonicalPath().substring(file.getCanonicalPath().lastIndexOf("."));
	  } catch (IOException ex) {
		Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex);
	  }
		File f2=new File("/home/celebron/Belgeler/Workspace/BenimEtum/web/uploads/"+id+type);
	  try {
		file.renameTo(f2);
		file.delete();
		Sparql.insertProperty(ETU+id, RDF+"type", ETU+"File");
		Sparql.insertLiteral(ETU+id, ETU+"uri", "uploads/"+id+type);
		Sparql.insertLiteral(ETU+id, ETU+"information", information);
	  } catch (DatabaseConnectException ex) {
		return null;
	  } catch (DatabaseWriteOrDeleteException ex) {
		return null;
	  }
	  return id;
    }
    
    /**
     * dosyayı dosya sisteminden siler
     * @param id
     * @return 
     */
    private static boolean deleteFile(String id){
	  try {
		File file=new File("uploads/"+id);
		file.delete();
		Sparql.removeLiteral(ETU+id, ETU+"uri");
		Sparql.removeLiteral(ETU+id, ETU+"information");
		Sparql.removeResource(ETU+id, RDF+"type", ETU+"File");
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  } catch (DatabaseConnectException ex) {
		return false;
	  }
	  return true;
    }
    
    /**
     * dosya ile classı eşleştirir
     * @param File
     * @param information
     * @param classId
     * @return 
     */
    public static boolean addFile(File File, String information,String classId){
	  String fileId = uploadFile(File, information);
	  if(fileId==null)
		return false;
	  try {
		Sparql.insertProperty(ETU+fileId, ETU+"addedTo", ETU+classId);
		Sparql.insertProperty(ETU+classId, ETU+"hasFiles", ETU+fileId);
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  } 
	  return true;
    }
    
    public static boolean addProfilePicture(File file, String userId){
	  Random random=new Random();
	  String id="img"+random.nextInt(10000000);
	  String type;
	  try {
		type = file.getCanonicalPath().substring(file.getCanonicalPath().lastIndexOf("."));
		File f2=new File("/home/celebron/Belgeler/Workspace/BenimEtum/web/img/"+id+type);
		file.renameTo(f2);
		Sparql.removeLiteral(ETU+userId, ETU+"profilePicture");
		Sparql.insertLiteral(ETU+userId, ETU+"profilePicture", "img/"+id+type);
		LoginManager.getUser().setProfilePicture("img/"+id+type);
	  } catch (DatabaseWriteOrDeleteException ex) {
		return false;
	  } catch (DatabaseConnectException ex) {
		return false;
	  } catch (IOException ex) {
		return false;
	  }
	  return true;
    }
    
    /**
     * dosyayı hem database hemde dosya sisteminden siler
     * @param fileId
     * @return 
     */
    public static boolean removeFile(String fileId){
	  boolean deleteFile = deleteFile(fileId);
	  if(deleteFile==true){
		try {
		    String classId=getFileClassId(fileId);
		    Sparql.removeResource(ETU+fileId, ETU+"addedTo", ETU+classId);
		    Sparql.removeResource(ETU+classId, ETU+"hasFiles", ETU+fileId);
		} catch (DatabaseWriteOrDeleteException ex) {
		    return false;
		} catch (DatabaseConnectException ex) {
		    return false;
		}
	  }
	  return true;
    }
    
    /**
     * dosyanın bağlı olduğu class idsini döndürür
     * @param fileId
     * @return 
     */
    public static String getFileClassId(String fileId){
	  String query="select ?id where {?file rdf:type etu:File. ?file etu:uri \""+"uploads/"+fileId+"\". ?file etu:addedTo ?class. ?class etu:id ?id}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  return toList.get(0).get("id").toString();
    }
    
    /**
     * verilen idli dosyayı döndürür
     * @param fileId
     * @return 
     */
    public static UploadedFile getFile(String fileId){
	  String query="select ?info where {?file rdf:type etu:File. ?file etu:uri \""+"uploads/"+fileId+"\". ?file etu:information ?info.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  UploadedFile file=null;
	  if(!toList.isEmpty()){
		file=new UploadedFile(new File("uploads/"+fileId), toList.get(0).get("info").toString());
	  }
	  return file;
    }
    
    /**
     * dersin tüm dosyalarını döndürür
     * @param courseId
     * @return 
     */
    public static UploadedFile[] getCoursesFiles(String courseId){
	  String query="select ?uri ?info where {?course rdf:type etu:Course.?course etu:id \""+courseId+"\". ?course etu:hasFiles ?file. ?file etu:uri ?uri. ?file etu:information ?info.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Sparql.close();
	  ArrayList<UploadedFile> files=new ArrayList<UploadedFile>();
	  if(!toList.isEmpty()){
		files.add(new UploadedFile(new File(toList.get(0).get("uri").toString()), toList.get(0).get("info").toString()));
	  }
	  UploadedFile[] array=new UploadedFile[files.size()];
	  return files.toArray(array);
    }
    
    /**
     * ödevin tüm dosyalarını döndürür
     * @param homeworkId
     * @return 
     */
    public static UploadedFile[] getHomeworksFiles(String homeworkId){
	  String query="select ?uri ?info where {?homework rdf:type etu:Homework. ?homework etu:id \""+homeworkId+"\". ?homework etu:hasFiles ?file. ?file etu:uri ?uri. ?file etu:information ?info.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
          Iterator<QuerySolution> iterator = toList.iterator();
          Sparql.close();
	  ArrayList<UploadedFile> files=new ArrayList<UploadedFile>();
	  while (iterator.hasNext()) {
                QuerySolution querySolution = iterator.next();
                files.add(new UploadedFile(new File(querySolution.get("uri").toString()), querySolution.get("info").toString()));
            }
	  UploadedFile[] array=new UploadedFile[files.size()];
	  return files.toArray(array);
    }
    
    /**
     * idsi verilen cevabın tüm dosyalarını döndürür
     * @param answerId
     * @return 
     */
    public static UploadedFile[] getAnswersFiles(String answerId){
	  String query="select ?uri ?info where {?answer rdf:type etu:Answer. ?answer etu:id \""+answerId+"\". ?answer etu:hasFiles ?file. ?file etu:uri ?uri. ?file etu:information ?info.}";
	  ResultSet search = Sparql.search(query);
	  List<QuerySolution> toList = ResultSetFormatter.toList(search);
        Iterator<QuerySolution> iterator = toList.iterator();
          Sparql.close();
	  ArrayList<UploadedFile> files=new ArrayList<UploadedFile>();
	    while (iterator.hasNext()) {
                QuerySolution querySolution = iterator.next();
                files.add(new UploadedFile(new File(querySolution.get("uri").toString()), querySolution.get("info").toString()));
            }	
	  UploadedFile[] array=new UploadedFile[files.size()];
	  return files.toArray(array);
    }
    
    public static File convertUploadedFileToFile(org.primefaces.model.UploadedFile file){
	  InputStream inputStream = null;
	  try {
		String name="tmp"+new Random().nextInt(10000000)+file.getFileName().substring(file.getFileName().lastIndexOf("."));
		File f=new File(name);
		inputStream = file.getInputstream();
		OutputStream out=new FileOutputStream(f);
		byte buf[]=new byte[1024];
		int len;
		while((len=inputStream.read(buf))>0)
		out.write(buf,0,len);
		out.close();
		inputStream.close();
		return f;
	  } catch (IOException ex) {
		return null;
	  } 
    }
}
    